home *** CD-ROM | disk | FTP | other *** search
- IDEAL
- JUMPS
- P386 ; 386 specific opcodes and shit allowed.
-
- ;************************************************************************
- ;
- ; FIREKIT v1.0
- ;
- ; by
- ;
- ; John W. Ractliff
- ; 70253.3237@compuserve.com
- ; jratclif@inlink.com
- ;
- ; 32bit DOS4GW application.
- ; Will run in Microsoft Windowss 32 bit mode.
- ; Source code in ANSI C and Turbo Assembler
- ;
- ;
- ;The enclosed software was written by John W. Ratcliff on May 27, 1996.
- ;As of this date I am releasing this software into the public domain.
- ;
- ;I am releasing this software into the public domain, hopefully, to make
- ;a point. I would like to demonstrate how to write source code that is
- ;useful to other people. I was looking at some of the various flame
- ;algorithms and source code examples and in each case they were such hard
- ;coded demos nobody could actually get them integrated into an
- ;application.
- ;************************************************************************/
-
- MODEL FLAT,C ;32-bit OS/2 model
-
- public FlameStart
- public FlameFrame
- public FlameCopy
- public FlameStop
- public FlameZeroScreen
- public FlameImage
- public FlameDAC
- public FlamePal
- public FlameCopyTranslate
- public FlameClosestColor
-
- Macro useall
- uses ebx,ecx,edx,esi,edi
- endm
-
- FWID equ 320 ; default flame width.
-
- Struc FLAMESPEC
-
- width dd ? ; width of flame buffer.
- height dd ? ; height of flame buffer.
- fsize dd ? ; length, width*height, of flame buffer.
- andmask dd ? ; fuel dump and mask, controls how many dumps are made.
- flame1 dd ? ; address of flame buffer #1
- flame2 dd ? ; address of flame buffer #2
- jitter dd ? ; 512 long word jitter table.
- seed dd ? ; random number seed.
- fheight dd ? ; flame consumption value.
- fuel dd ? ; size of fuel dumps.
- fuelbase dd ? ; base fuel fed at bottom.
- fire8 dd ? ; flag is true if doing 8 pixel average of fire.
- ScreenX dd ? ; destination screen x copy location.
- ScreenY dd ? ; destination screen y copy location.
- ctrans db 256 dup(?) ;the color translation table if used.
-
- Ends
- DATASEG
-
- lastwid dd FWID ; last width self-modified in the code.
-
- label pal byte
- rept 8
- db 0,0,0
- endm
-
- i=0
- rept 8
- db i*2, 0, 0
- i=i+1
- endm
- i=0
- rept 16
- db 16+47*i/16, 0, 0
- i=i+1
- endm
- i=0
- rept 24
- db 63, 21*i/8, 0
- i=i+1
- endm
- i=0
- rept 24
- db 63, 63, 21*i/8
- i=i+1
- endm
-
- db 179*3 dup(63)
-
- CODESEG
-
- ;; Init the screen.
- Proc C FlameStart near
- useall
-
- mov eax, 0013h ; mode 13h
- int 10h ; turn 320x200 mode on.
-
- mov edx,3c8h ; set the color palette.
- xor al,al
- out dx,al
- inc dx
- mov ecx,256*3
- lea esi,[pal]
-
- @@p1: mov al, [esi]
- out dx, al
- inc esi
- dec ecx
- jnz @@p1
-
- ret
- endp
-
- Proc C FlameFrame near
- arg fl:dword
- local fuel:dword
- useall
-
- mov ebx,[fl]
-
- mov eax,[(FLAMESPEC ebx).width]
- cmp eax,[lastwid] ; same as current modification?
- je @@OK
-
- ;; Here we must self-modify all of the instructions which have
- ;; hard-coded offsets based on the width of the image being filtered.
- ;; There is no way around this self-modified code, period!
- ;; The first 8 instructions to modify all have an offset of 3 bytes
- ;; While MOD9-MOD12 have an offset of 2 bytes
- mov edx,eax ; EDX has -width.
- neg edx ;
- mov [MOD1+3],edx ; -WIDTH
- mov [MOD2+3],eax ; +WIDTH
- inc eax ; WIDTH+1
- neg eax ; Make it negative
- mov [MOD3+3],eax ; -(WIDTH+1)
- neg eax ; +(WIDTH+1)
- mov [MOD4+3],eax
- sub eax,2 ; now equal width-1
- neg eax ; -(width-1)
- mov [MOD5+3],eax
- neg eax ; now + (width-1)
- mov [MOD6+3],eax ;
- inc eax ; back to positive width.
- mov [MOD7+3],edx ; -width
- mov [MOD8+3],eax ; +width
- mov [MOD9+2],edx ; -width
- mov [MOD10+2],eax ; +width
- mov [MOD11+2],edx ; -width
- mov [MOD12+2],eax ; +width
-
- @@OK:
-
- mov eax,[(FLAMESPEC ebx).fuel]
- mov [fuel],eax
-
- mov esi,[(FLAMESPEC ebx).flame1] ; current source frame.
- mov edi,[(FLAMESPEC ebx).flame2] ; current destination frame.
- add esi,[(FLAMESPEC ebx).width]
- inc esi ; width +1
- inc edi ; base address of desintation.
- ;; ECX = wid*hit-(wid+2)
- mov ecx,[(FLAMESPEC ebx).fsize] ; Length of buffer.
- mov eax,[(FLAMESPEC ebx).width] ; minus width+2
- shl eax,1
- add eax,2
- sub ecx,eax
-
- ;; Each pixel is equal to the mean sum of the one left/right, up and down
- ;; on the previous frame.
- mov edx,[(FLAMESPEC ebx).fheight] ; height of flame.
- cmp [(FLAMESPEC ebx).fire8],0 ; doing normal 4 pixel average?
- je @@l1
-
- @@k1:
- LABEL MOD1 DWORD
- movzx ebx,[byte esi-FWID] ; get first byte.
- LABEL MOD2 DWORD
- movzx eax,[byte esi+FWID] ; get next byte
- add ebx,eax ; add into total.
- movzx eax,[byte esi-1] ; get next byte.
- add ebx,eax ; add into total.
- movzx eax,[byte esi+1] ; get fourth byte
- add ebx,eax ; have complte summation.
- LABEL MOD3 DWORD
- movzx eax,[byte esi-(FWID+1)]
- add ebx,eax
- LABEL MOD4 DWORD
- movzx eax,[byte esi+(FWID+1)]
- add ebx,eax
- LABEL MOD5 DWORD
- movzx eax,[byte esi-(FWID-1)]
- add ebx,eax
- LABEL MOD6 DWORD
- movzx eax,[byte esi+(FWID-1)]
- add eax,ebx
- shr eax,3
- sub eax,edx
- jns @@k2
- xor eax,eax
- @@k2: mov [edi],al ; store result.
- inc edi
- inc esi
- dec ecx
- jnz @@k1
-
- jmp @@cont ; re-enter rest of code.
-
- @@l1:
- LABEL MOD7 DWORD
- movzx ebx,[byte esi-FWID] ; get first byte.
- LABEL MOD8 DWORD
- movzx eax,[byte esi+FWID] ; get next byte
- add ebx,eax ; add into total.
- movzx eax,[byte esi-1] ; get next byte.
- add ebx,eax ; add into total.
- movzx eax,[byte esi+1] ; get fourth byte
- add eax,ebx ; have complte summation.
- shr eax,2
- sub eax,edx
- jns @@l2
- xor eax,eax
- @@l2:
- mov [edi],al ; store result.
- inc edi
- inc esi
- dec ecx
- jnz @@l1
- @@cont:
-
- ;; Randomize the bottom 3 scanlines of next frame.
- mov edx,69069 ; a prime number.
- mov ebx,[fl] ; address of flamespec
- mov edi,[(FLAMESPEC ebx).flame2] ; destination.
- mov eax,[(FLAMESPEC ebx).width]
- shl eax,1
- add edi,[(FLAMESPEC ebx).fsize] ; add size of buffer.
- sub edi,eax ; less width *2
- mov ecx,[(FLAMESPEC ebx).width] ; randomize scanline.
- mov eax,[(FLAMESPEC ebx).seed]
- mov ebx,[(FLAMESPEC ebx).fuelbase]
- shl ebx,8
- ;; Adding fuel to the fire.
- @@l3:
- imul eax,edx
- inc eax ; Plus 1
- mov bl,ah
- and bl,0fh
- add bl,bh
- LABEL MOD9 DWORD
- mov [edi-FWID],bl
-
- imul eax,edx
- inc eax
- mov bl,ah
- and bl,0fh
- add bl,bh
- mov [edi],bl
-
- imul eax,edx
- inc eax
- mov bl,ah
- and bl,0fh
- add bl,bh
- add bl,bh
- LABEL MOD10 DWORD
- mov [edi+FWID],bl
- inc edi
- dec ecx
- jnz @@l3
-
- ;; This is a random-jitter function that forces the flames to bubble/roil.
- ;; This forces raw fuel into a random number of pixels.
- push eax ; preserve current random number.
-
- mov ebx,[fl] ; address of flamespec.
- mov esi,[(FLAMESPEC ebx).flame2]
- add esi,[(FLAMESPEC ebx).fsize]
- mov eax,[(FLAMESPEC ebx).width]
- shl eax,1
- sub esi,eax ; bottom scanline-2
- pop eax
-
- imul eax,edx
- inc eax
- mov cl,al
- and ecx,[(FLAMESPEC ebx).andmask] ; and
- jz @@EMPTY
- ; the number of pixel to add fuel to.
- mov edi,[(FLAMESPEC ebx).jitter] ; get 512 dword jitter table.
-
- ;; EAX/EDX random number.
- ;; EBX - scratch.
- ;; ECX - Count.
- ;; ESI - base for scanline.
- ;; EDI - base address of 512 entry jitter table.
-
- @@l4: imul eax,edx
- inc eax ; compute random
- mov ebx,eax ; random into EBX
- xchg bl,bh ; swap low/high to make it interesting.
- and ebx,511 ; top 512 entries.
- mov ebx,[edi+ebx*4] ; pull *valid* offset from jitter table.
- add ebx,esi ; plus base.
- push eax ; preserve current random number.
-
- ;; Fuel Dump
-
- mov eax,[fuel]
- LABEL MOD11 DWORD
- mov [ebx-FWID],al ; dump line above.
- LABEL MOD12 DWORD
- mov [ebx+FWID],al ; dump line below.
-
- mov [ebx-1],al ; dump left
- mov [ebx+1],al ; dump right
- mov [ebx],al ; dump current.
-
- pop eax
-
- dec ecx
- jnz @@l4
- @@EMPTY:
-
- mov ebx,[fl]
- mov [(FLAMESPEC ebx).seed],eax
- mov eax,[(FLAMESPEC ebx).flame1]
- mov ecx,[(FLAMESPEC ebx).flame2]
- mov [(FLAMESPEC ebx).flame1],ecx
- mov [(FLAMESPEC ebx).flame2],eax
-
- ret
- endp
-
- ;; This actually copies the flame to the screen, and then flip/flops the
- ;; buffers.
- Proc C FlameCopy near
- arg fl:dword
- useall
-
- mov ebx,[fl]
- mov esi,[(FLAMESPEC ebx).flame1]
- lea edi,[0A0000h] ; in Watcom DOS4gw, hard coded physical address.
-
- mov eax,320
- imul [(FLAMESPEC ebx).ScreenY]
- add eax,[(FLAMESPEC ebx).ScreenX]
- add edi,eax ; dest screen scanline.
-
- mov ecx,[(FLAMESPEC ebx).width]
- shr ecx,2 ; /4 movsd
- mov edx,[(FLAMESPEC ebx).height]
- sub edx,3
- @@GO:
- push edi
- push ecx
- rep movsd
- pop ecx
- pop edi
- add edi,320
- dec edx
- jnz @@GO
-
-
- ret
- endp
-
-
- Proc C FlameStop near
- useall
-
- mov eax,03h
- int 10h ; back to text mode.
-
- ret
- endp
-
- Proc C FlameZeroScreen near
- useall
-
- mov edi,0A0000h
- xor eax,eax
- mov ecx,64000/4
- rep stosd
-
- ret
- endp
-
- Proc C FlameImage near
- arg image:dword
- useall
-
- mov esi,[image]
- mov edi,0A0000h
- mov ecx,64000/4
- rep movsd
-
- ret
- endp
-
- Proc C FlameDAC near
- arg fpal:dword
- useall
-
- mov edx,3c8h ; set the color palette.
- xor al,al
- out dx,al
- inc dx
- mov ecx,256*3
- mov esi,[fpal]
-
- @@p1: mov al, [esi]
- shr al,2 ; into 5 bit format.
- out dx,al
- inc esi
- dec ecx
- jnz @@p1
-
- ret
- endp
-
- Proc C FlamePal near
- arg fpal:dword
- useall
-
- mov edi,[fpal]
- lea esi,[pal]
- mov edx,3c8h ; set the color palette.
- xor al,al
- out dx,al
- inc dx
- mov ecx,256*3
-
- @@p1: mov al,[esi]
- shl al,2
- mov [edi],al
- shr al,2
- out dx, al
- inc esi
- inc edi
- dec ecx
- jnz @@p1
-
- ret
- endp
-
- ;; This actually copies the flame to the screen, and then flip/flops the
- ;; buffers.
- Proc C FlameCopyTranslate near
- arg fl:dword,image:dword
- useall
-
- mov ebx,[fl]
- mov esi,[(FLAMESPEC ebx).flame1]
- mov edi,[image] ; in Watcom DOS4gw, hard coded physical address.
-
- mov eax,320
- imul [(FLAMESPEC ebx).ScreenY]
- add eax,[(FLAMESPEC ebx).ScreenX]
- add edi,eax ; dest screen scanline.
-
- mov ecx,[(FLAMESPEC ebx).width]
- mov edx,[(FLAMESPEC ebx).height]
- lea ebx,[(FLAMESPEC ebx).ctrans] ; base address of color translate table.
- sub eax,eax ; zero out EAX
- sub edx,3 ; Don't do bottom 3 scanlines.
- @@GO:
- push edi
- push ecx
-
-
- @@MERG: mov al,[esi]
- inc esi
- cmp al,4
- jbe @@M0
- mov al,[ebx+eax] ; color translate flame.
- mov [edi],al
- @@M0: inc edi
- dec ecx
- jnz @@MERG
-
- pop ecx
- pop edi
- add edi,320
- dec edx
- jnz @@GO
-
-
- ret
- endp
-
- Macro Error COLOR
- LOCAL @@OK
- xor eax,eax
- lodsb ; Get color.
- sub eax,[COLOR]
- jns @@OK
- neg eax
- @@OK: push ebx ; Save current error.
- mov ebx,eax ; Into BX, difference.
- mul bl ; Square it.
- pop ebx ; Restore current error.
- add ebx,eax ; Add into total error.
- endm
-
- Proc C FlameClosestColor near
- ARG PALETTE:DWORD,R:DWORD,G:DWORD,B:DWORD
- LOCAL DOMINANT:WORD
- useall
-
- mov esi,[PALETTE]
- mov edx,0FFFFFFFFh ; Minimum error initially found.
- xor ecx,ecx ; for all 256 colors.
- @@FIND:
- mov al,[esi] ; Get red
- mov ah,[esi+1] ; Get green.
- mov bl,[esi+2] ; Get blue.
- xor ebx,ebx ; Total error.
- Error R
- Error G
- Error B
- cmp ebx,edx ; Less then previous minimum error?
- jae @@NOT
- mov edx,ebx ; New minimum error.
- mov edi,ecx ; Save minimum error loc.
- @@NOT: inc ecx
- cmp ecx,256
- jne @@FIND
-
- mov eax,edi ; Closest match.
-
- ret
- endp
-
- END
-